package com.gx.city_picker;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Dialog;
import android.content.Context;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.gx.city_picker.adpater.AreaAdapter;
import com.gx.city_picker.adpater.CityAdapter;
import com.gx.city_picker.adpater.ProvincesAdapter;
import com.gx.city_picker.adpater.TownAdapter;
import com.gx.city_picker.entity.AreaEntity;
import com.gx.city_picker.entity.CityEntity;
import com.gx.city_picker.entity.ProvinceEntity;
import com.gx.city_picker.entity.TownEntity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * 仿京东的城市选择器
 * <p>
 * 可配置联动级别，最大支持四级联动
 * <p>
 * 可自定义标题
 * <p>
 * 可添加回调监听
 * <p>
 * Created by Guoxin on 2021-08-20
 */
public class CityPickerDialog extends Dialog implements View.OnClickListener {

    public static CityPickerDialog Build(Context context) {
        return new CityPickerDialog(context);
    }

    public static final int CITY_PICKER_LEVEL1 = 1; // 省   一级联动
    public static final int CITY_PICKER_LEVEL2 = 2; // 市   二级联动
    public static final int CITY_PICKER_LEVEL3 = 3; // 县   三级联动
    public static final int CITY_PICKER_LEVEL4 = 4; // 镇   四级联动

    private Context         mContext;
    private AddressListener mAddressListener;
    private int             mLevel = CITY_PICKER_LEVEL3; // 默认 为三级联动

    /**
     * 标题
     */
    private String mTitle = "";

    /**
     * 标题字体颜色
     */
    private int    mTitleColor   = R.color.city_picker_text_999;

    /**
     * 当前选择的字体颜色
     */
    private int    mSelectColor = R.color.city_picker_primary;

    /**
     * 未选中的字体颜色
     */
    private int    mDefaultColor = R.color.city_picker_text_color;

    /**
     * 选中时底部的线颜色
     */
    private int    mLineColor    = R.color.city_picker_primary;

    private TextView     mTitleTv;
    private ImageView    mCloseIv;
    private TextView     mProvinceTv;
    private TextView     mCityTv;
    private TextView     mAreaTv;
    private TextView     mTownTv;
    private View         mLine;
    private RecyclerView mRv;

    private ProvincesAdapter mProvincesAdapter;
    private CityAdapter      mCityAdapter;
    private AreaAdapter      mAreaAdapter;
    private TownAdapter      mTownAdapter;

    private List<ProvinceEntity> mProvincesData;
    private List<CityEntity>     mCityData;
    private List<AreaEntity>     mAreaData;
    private List<TownEntity>     mTownData;

    private ProvinceEntity provincesVo;
    private CityEntity     cityVo;
    private AreaEntity     areasVo;
    private TownEntity     townsVo;

    private int index = 0;

    public interface AddressListener {
        void callBack(int level, ProvinceEntity province, CityEntity city, AreaEntity area, TownEntity town);
    }

    public CityPickerDialog(@NonNull Context context) {
        super(context, R.style.city_picker_dialog_style);
        this.mContext = context;
    }

    public CityPickerDialog setAddressListener(AddressListener addressListener) {
        this.mAddressListener = addressListener;
        return this;
    }

    public CityPickerDialog setLevel(int level) {
        this.mLevel = level;
        return this;
    }

    public CityPickerDialog setTitle(String title) {
        this.mTitle = title;
        return this;
    }

    public CityPickerDialog setTitleColor(int titleColor) {
        this.mTitleColor = titleColor;
        return this;
    }

    public CityPickerDialog setSelectColor(int selectColor) {
        this.mSelectColor = selectColor;
        return this;
    }

    public CityPickerDialog setDefaultColor(int defaultColor) {
        this.mDefaultColor = defaultColor;
        return this;
    }

    public CityPickerDialog setLineColor(int lineColor) {
        this.mLineColor = lineColor;
        return this;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.city_picker_dialog);
        initView();
        initData();
        initListener();
        initParas();
    }

    private void initView() {
        this.mTitleTv = findViewById(R.id.title_tv);
        this.mCloseIv = findViewById(R.id.close_iv);
        this.mProvinceTv = findViewById(R.id.province_tv);
        this.mCityTv = findViewById(R.id.city_tv);
        this.mAreaTv = findViewById(R.id.area_tv);
        this.mTownTv = findViewById(R.id.town_tv);
        this.mLine = findViewById(R.id.line);
        this.mRv = findViewById(R.id.rv);
        this.mRv.setLayoutManager(new LinearLayoutManager(mContext));
    }

    private void initData() {
        this.mLine.setBackgroundColor(mContext.getColor(mLineColor));
        this.mProvincesAdapter = new ProvincesAdapter(mContext, mSelectColor, mDefaultColor);
        this.mCityAdapter = new CityAdapter(mContext, mSelectColor, mDefaultColor);
        this.mAreaAdapter = new AreaAdapter(mContext, mSelectColor, mDefaultColor);
        this.mTownAdapter = new TownAdapter(mContext, mSelectColor, mDefaultColor);

        this.mTitleTv.setText(mTitle);
        this.mTitleTv.setTextColor(mContext.getColor(mTitleColor));

        this.mProvincesData = getCity();

        this.index = 0;
        this.mProvincesAdapter.setDatas(mProvincesData);
        this.mRv.setAdapter(mProvincesAdapter);
        this.mProvinceTv.setTextColor(mContext.getColor(mSelectColor));
        this.mCityTv.setTextColor(mContext.getColor(mDefaultColor));
        this.mAreaTv.setTextColor(mContext.getColor(mDefaultColor));
        this.mTownTv.setTextColor(mContext.getColor(mDefaultColor));
        this.mProvinceTv.setVisibility(View.VISIBLE);
        this.mCityTv.setVisibility(View.GONE);
        this.mAreaTv.setVisibility(View.GONE);
        this.mTownTv.setVisibility(View.GONE);
        tabSelectedIndicatorAnimation(mProvinceTv);
    }

    private void initListener() {
        this.mCloseIv.setOnClickListener(this);
        this.mProvinceTv.setOnClickListener(this);
        this.mCityTv.setOnClickListener(this);
        this.mAreaTv.setOnClickListener(this);
        this.mProvincesAdapter.setListener((position, o) -> {
            provincesVo = (ProvinceEntity) o;
            if (mLevel == CITY_PICKER_LEVEL1) {
                dismiss();
                if (null != mAddressListener) {
                    mAddressListener.callBack(mLevel, provincesVo, null, null, null);
                }
                return;
            }
            index = 1;
            cityVo = null;
            areasVo = null;
            townsVo = null;
            mCityData = mProvincesData.get(position).getCityList();
            if (null == mCityData || mCityData.isEmpty()) {
                return;
            }
            mCityAdapter.setDatas(mCityData);
            mCityAdapter.setSelector(null);
            mRv.setAdapter(mCityAdapter);
            mProvinceTv.setTextColor(mContext.getColor(mDefaultColor));
            mCityTv.setTextColor(mContext.getColor(mSelectColor));
            mAreaTv.setTextColor(mContext.getColor(mDefaultColor));
            mTownTv.setTextColor(mContext.getColor(mDefaultColor));
            mProvinceTv.setVisibility(View.VISIBLE);
            mCityTv.setVisibility(View.VISIBLE);
            mAreaTv.setVisibility(View.GONE);
            mTownTv.setVisibility(View.GONE);
            mProvinceTv.setText(provincesVo.getProvinceName());
            mCityTv.setText("请选择");
            tabSelectedIndicatorAnimation(mCityTv);
        });
        this.mCityAdapter.setListener((position, o) -> {
            cityVo = (CityEntity) o;
            if (mLevel == CITY_PICKER_LEVEL2) {
                dismiss();
                if (null != mAddressListener) {
                    mAddressListener.callBack(mLevel, provincesVo, cityVo, null, null);
                }
                return;
            }
            index = 2;
            areasVo = null;
            townsVo = null;
            mAreaData = mCityData.get(position).getAreaList();
            if (null == mAreaData || mAreaData.isEmpty()) {
                return;
            }
            mAreaAdapter.setDatas(mAreaData);
            mAreaAdapter.setSelector(null);
            mRv.setAdapter(mAreaAdapter);
            mProvinceTv.setTextColor(mContext.getColor(mDefaultColor));
            mCityTv.setTextColor(mContext.getColor(mDefaultColor));
            mAreaTv.setTextColor(mContext.getColor(mSelectColor));
            mTownTv.setTextColor(mContext.getColor(mDefaultColor));
            mProvinceTv.setVisibility(View.VISIBLE);
            mCityTv.setVisibility(View.VISIBLE);
            mAreaTv.setVisibility(View.VISIBLE);
            mTownTv.setVisibility(View.GONE);
            mProvinceTv.setText(provincesVo.getProvinceName());
            mCityTv.setText(cityVo.getCityName());
            mAreaTv.setText("请选择");
            tabSelectedIndicatorAnimation(mAreaTv);
        });
        this.mAreaAdapter.setListener((position, o) -> {
            areasVo = (AreaEntity) o;
            if (mLevel == CITY_PICKER_LEVEL3) {
                dismiss();
                if (null != mAddressListener) {
                    mAddressListener.callBack(mLevel, provincesVo, cityVo, areasVo, null);
                }
                return;
            }
            index = 3;
            townsVo = null;
            mTownData = mAreaData.get(position).getTownList();
            if (null == mTownData || mTownData.isEmpty()) {
                return;
            }
            mTownAdapter.setDatas(mTownData);
            mTownAdapter.setSelector(null);
            mRv.setAdapter(mTownAdapter);
            mProvinceTv.setTextColor(mContext.getColor(mDefaultColor));
            mCityTv.setTextColor(mContext.getColor(mDefaultColor));
            mAreaTv.setTextColor(mContext.getColor(mDefaultColor));
            mTownTv.setTextColor(mContext.getColor(mSelectColor));
            mProvinceTv.setVisibility(View.VISIBLE);
            mCityTv.setVisibility(View.VISIBLE);
            mAreaTv.setVisibility(View.VISIBLE);
            mTownTv.setVisibility(View.VISIBLE);
            mProvinceTv.setText(provincesVo.getProvinceName());
            mCityTv.setText(cityVo.getCityName());
            mAreaTv.setText(areasVo.getAreaName());
            mTownTv.setText("请选择");
            tabSelectedIndicatorAnimation(mTownTv);
        });
        this.mTownAdapter.setListener((position, o) -> {
            townsVo = (TownEntity) o;
            dismiss();
            if (null != mAddressListener) {
                mAddressListener.callBack(mLevel, provincesVo, cityVo, areasVo, townsVo);
            }
        });
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.close_iv) {
            dismiss();
        }
        else if (id == R.id.province_tv) {
            if (index == 0) {
                return;
            }
            index = 0;
            cityVo = null;
            areasVo = null;
            townsVo = null;
            mProvincesAdapter.setSelector(provincesVo);
            mRv.setAdapter(mProvincesAdapter);
            mProvinceTv.setTextColor(mContext.getColor(mSelectColor));
            mCityTv.setTextColor(mContext.getColor(mDefaultColor));
            mAreaTv.setTextColor(mContext.getColor(mDefaultColor));
            mTownTv.setTextColor(mContext.getColor(mDefaultColor));
            mProvinceTv.setVisibility(View.VISIBLE);
            mCityTv.setVisibility(View.GONE);
            mAreaTv.setVisibility(View.GONE);
            mTownTv.setVisibility(View.GONE);
            mProvinceTv.setText(provincesVo.getProvinceName());
            tabSelectedIndicatorAnimation(mProvinceTv);
        }
        else if (id == R.id.city_tv) {
            if (index == 1) {
                return;
            }
            index = 1;
            areasVo = null;
            townsVo = null;
            mCityAdapter.setSelector(cityVo);
            mRv.setAdapter(mCityAdapter);
            mProvinceTv.setTextColor(mContext.getColor(mDefaultColor));
            mCityTv.setTextColor(mContext.getColor(mSelectColor));
            mAreaTv.setTextColor(mContext.getColor(mDefaultColor));
            mTownTv.setTextColor(mContext.getColor(mDefaultColor));
            mProvinceTv.setVisibility(View.VISIBLE);
            mCityTv.setVisibility(View.VISIBLE);
            mAreaTv.setVisibility(View.GONE);
            mTownTv.setVisibility(View.GONE);
            tabSelectedIndicatorAnimation(mCityTv);
        }
        else if (id == R.id.area_tv) {
            if (index == 2) {
                return;
            }
            index = 2;
            townsVo = null;
            mAreaAdapter.setSelector(areasVo);
            mRv.setAdapter(mAreaAdapter);
            mProvinceTv.setTextColor(mContext.getColor(mDefaultColor));
            mCityTv.setTextColor(mContext.getColor(mDefaultColor));
            mAreaTv.setTextColor(mContext.getColor(mSelectColor));
            mTownTv.setTextColor(mContext.getColor(mDefaultColor));
            mProvinceTv.setVisibility(View.VISIBLE);
            mCityTv.setVisibility(View.VISIBLE);
            mAreaTv.setVisibility(View.VISIBLE);
            mTownTv.setVisibility(View.GONE);
            tabSelectedIndicatorAnimation(mAreaTv);
        }
    }

    /**
     * tab 选中的红色下划线动画
     *
     * @param tab
     * @return
     */
    private void tabSelectedIndicatorAnimation(TextView tab) {
        tab.post(() -> {
            ObjectAnimator xAnimator = ObjectAnimator.ofFloat(mLine, "X", mLine.getX(), tab.getX());
            ViewGroup.LayoutParams params = mLine.getLayoutParams();
            ValueAnimator widthAnimator = ValueAnimator.ofInt(params.width, tab.getMeasuredWidth());
            widthAnimator.addUpdateListener(animation -> {
                params.width = (int) animation.getAnimatedValue();
                mLine.setLayoutParams(params);
            });
            AnimatorSet set = new AnimatorSet();
            set.setInterpolator(new FastOutSlowInInterpolator());
            set.playTogether(xAnimator, widthAnimator);
            set.start();
        });
    }

    /**
     * Setting Window Open Style
     */
    private void initParas() {
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        int width = outMetrics.widthPixels;

        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.gravity = Gravity.BOTTOM;
        params.width = width;
        getWindow().setAttributes(params);
    }

    /**
     * 读取本地城市JSON数据
     *
     * @return
     */
    private List<ProvinceEntity> getCity() {
        return new Gson().fromJson(getAssets("city_data.json", mContext), new TypeToken<List<ProvinceEntity>>() {}.getType());
    }

    private String getAssets(String fileName, Context context) {
        //将json数据变成字符串
        StringBuilder stringBuilder = new StringBuilder();
        try {
            //获取assets资源管理器
            AssetManager assetManager = context.getAssets();
            //通过管理器打开文件并读取
            BufferedReader bf = new BufferedReader(new InputStreamReader(assetManager.open(fileName)));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }
}
